package com.hellobike.haxing.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hellobike.haxing.common.constant.CommonConstant;
import com.hellobike.haxing.common.util.YouBianCodeUtil;
import com.hellobike.haxing.modules.system.entity.SysDepart;
import com.hellobike.haxing.modules.system.entity.SysDepartRole;
import com.hellobike.haxing.modules.system.mapper.SysDepartMapper;
import com.hellobike.haxing.modules.system.mapper.SysDepartRoleMapper;
import com.hellobike.haxing.modules.system.model.DepartIdModel;
import com.hellobike.haxing.modules.system.model.SysDepartTreeModel;
import com.hellobike.haxing.modules.system.service.ISysDepartService;
import com.hellobike.haxing.modules.system.util.FindsDepartsChildrenUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 部门表 服务实现类
 * <p>
 *
 * @Author Steve
 * @Since 2019-01-22
 */
@Service
public class SysDepartServiceImpl extends ServiceImpl<SysDepartMapper, SysDepart> implements ISysDepartService {


    @Autowired
    private SysDepartRoleMapper sysDepartRoleMapper;

    /**
     * queryTreeList 对应 queryTreeList 查询所有的部门数据,以树结构形式响应给前端
     */
//	@Cacheable(value = CacheConstant.SYS_DEPARTS_CACHE)
    @Override
    public List<SysDepartTreeModel> queryTreeList() {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDeleted, CommonConstant.DEL_FLAG_0);
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = this.list(query);
        List<SysDepartRole> departRoles = sysDepartRoleMapper.selectList(null);
        List<SysDepartTreeModel> listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList(list, departRoles);
        return listResult;
    }

    //@Cacheable(value = CacheConstant.SYS_DEPART_IDS_CACHE)
    @Override
    public List<DepartIdModel> queryDepartIdTreeList() {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getDeleted, CommonConstant.DEL_FLAG_0);
        query.orderByAsc(SysDepart::getDepartOrder);
        List<SysDepart> list = this.list(query);
        // 调用wrapTreeDataToTreeList方法生成树状数据
        List<DepartIdModel> listResult = FindsDepartsChildrenUtil.wrapTreeDataToDepartIdTreeList(list);
        return listResult;
    }

    /**
     * saveDepartData 对应 add 保存用户在页面添加的新的部门对象数据
     */
    @Override
    @Transactional
    public void saveDepartData(SysDepart sysDepart, String username) {


        if (sysDepart != null && username != null) {
            if (sysDepart.getParentId() == null) {
                sysDepart.setParentId(null);
            }
//			String s = UUID.randomUUID().toString().replace("-", "");
//			sysDepart.setId(s);
            // 先判断该对象有无父级ID,有则意味着不是最高级,否则意味着是最高级
            // 获取父级ID
            Long parentId = sysDepart.getParentId();
            String[] codeArray = generateOrgCode(parentId);
            sysDepart.setOrgCode(codeArray[0]);
            String orgType = codeArray[1];
            sysDepart.setOrgType(String.valueOf(orgType));
            sysDepart.setCreateTime(new Date());
            sysDepart.setDeleted(CommonConstant.DEL_FLAG_0);
            this.save(sysDepart);

            if (sysDepart.getDefaultRoleId() == null) {
                sysDepart.setDefaultRoleId(new ArrayList<>());
            } else {
                if (sysDepart.getParentId() != null) {
                    List<SysDepartRole> sysDepartRoles = sysDepartRoleMapper.selectList(new QueryWrapper<SysDepartRole>().lambda()
                            .eq(SysDepartRole::getDepartId, sysDepart.getParentId()));
                    List<Long> defaultRoleIdList = new ArrayList<>();
                    if (!CollectionUtils.isEmpty(sysDepartRoles)) {
                        for (SysDepartRole sysDepartRole : sysDepartRoles) {
                            defaultRoleIdList.add(sysDepartRole.getRoleId());
                        }
                    }
                    sysDepart.setDefaultRoleId(defaultRoleIdList);
                }
            }
            List<SysDepartRole> sysDepartRoles = sysDepartRoleMapper.selectList(new QueryWrapper<SysDepartRole>()
                    .lambda().eq(SysDepartRole::getDepartId, sysDepart.getId()));
            if (!CollectionUtils.isEmpty(sysDepartRoles)) {
                for (SysDepartRole sysDepartRole : sysDepartRoles) {
                    if (sysDepart.getDefaultRoleId().contains(sysDepartRole.getId())) {
                        sysDepart.getDefaultRoleId().remove(sysDepartRole.getId());
                    } else {
                        sysDepartRoleMapper.deleteById(sysDepartRole.getRoleId());
                    }
                }

            }
            if (CollectionUtils.isNotEmpty(sysDepart.getDefaultRoleId())) {
                for (Long roleId : sysDepart.getDefaultRoleId()) {
                    SysDepartRole sysDepartRole = new SysDepartRole();
                    sysDepartRole.setDepartId(sysDepart.getId());
                    sysDepartRole.setRoleId(roleId);
                    sysDepartRole.setDeleted(0);
                    sysDepartRoleMapper.insert(sysDepartRole);
                }
            }
        }

    }

    /**
     * saveDepartData 的调用方法,生成部门编码和部门类型
     *
     * @param parentId
     * @return
     */
    private String[] generateOrgCode(Long parentId) {
        //update-begin--Author:Steve  Date:20190201 for：组织机构添加数据代码调整
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        LambdaQueryWrapper<SysDepart> query1 = new LambdaQueryWrapper<SysDepart>();
        String[] strArray = new String[2];
        // 创建一个List集合,存储查询返回的所有SysDepart对象
        List<SysDepart> departList = new ArrayList<>();
        // 定义新编码字符串
        String newOrgCode = "";
        // 定义旧编码字符串
        String oldOrgCode = "";
        // 定义部门类型
        String orgType = "";
        // 如果是最高级,则查询出同级的org_code, 调用工具类生成编码并返回
        if (parentId == null) {
            // 线判断数据库中的表是否为空,空则直接返回初始编码
            //query1.eq(SysDepart::getParentId, null).or()
            query1.isNull(SysDepart::getParentId);
            query1.orderByDesc(SysDepart::getOrgCode);
            departList = this.list(query1);
            if (departList == null || departList.size() == 0) {
                strArray[0] = YouBianCodeUtil.getNextYouBianCode(null);
                strArray[1] = "1";
                return strArray;
            } else {
                SysDepart depart = departList.get(0);
                oldOrgCode = depart.getOrgCode();
                orgType = depart.getOrgType();
                newOrgCode = YouBianCodeUtil.getNextYouBianCode(oldOrgCode);
            }
        } else { // 反之则查询出所有同级的部门,获取结果后有两种情况,有同级和没有同级
            // 封装查询同级的条件
            query.eq(SysDepart::getParentId, parentId);
            // 降序排序
            query.orderByDesc(SysDepart::getOrgCode);
            // 查询出同级部门的集合
            List<SysDepart> parentList = this.list(query);
            // 查询出父级部门
            SysDepart depart = this.getById(parentId);
            // 获取父级部门的Code
            String parentCode = depart.getOrgCode();
            // 根据父级部门类型算出当前部门的类型
            orgType = String.valueOf(Integer.valueOf(depart.getOrgType()) + 1);
            // 处理同级部门为null的情况
            if (parentList == null || parentList.size() == 0) {
                // 直接生成当前的部门编码并返回
                newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, null);
            } else { //处理有同级部门的情况
                // 获取同级部门的编码,利用工具类
                String subCode = parentList.get(0).getOrgCode();
                // 返回生成的当前部门编码
                newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, subCode);
            }
        }
        // 返回最终封装了部门编码和部门类型的数组
        strArray[0] = newOrgCode;
        strArray[1] = orgType;
        return strArray;
        //update-end--Author:Steve  Date:20190201 for：组织机构添加数据代码调整
    }


    /**
     * removeDepartDataById 对应 delete方法 根据ID删除相关部门数据
     *
     */
    /*
     * @Override
     *
     * @Transactional public boolean removeDepartDataById(String id) {
     * System.out.println("要删除的ID 为=============================>>>>>"+id); boolean
     * flag = this.removeById(id); return flag; }
     */

    /**
     * updateDepartDataById 对应 edit 根据部门主键来更新对应的部门数据
     */
    @Override
    @Transactional
    public Boolean updateDepartDataById(SysDepart sysDepart, String username) {
        if (sysDepart != null && username != null) {
            sysDepart.setUpdateTime(new Date());
//			sysDepart.setUpdateBy(username);
            this.updateById(sysDepart);
            List<SysDepartRole> sysDepartRoles = sysDepartRoleMapper.selectList(new QueryWrapper<SysDepartRole>()
                    .lambda().eq(SysDepartRole::getDepartId, sysDepart.getId()));
            if (!CollectionUtils.isEmpty(sysDepartRoles)) {
                for (SysDepartRole sysDepartRole : sysDepartRoles) {
                    if (sysDepart.getDefaultRoleId().contains(sysDepartRole.getId())) {
                        sysDepart.getDefaultRoleId().remove(sysDepartRole.getId());
                    } else {
                        sysDepartRoleMapper.deleteById(sysDepartRole.getRoleId());
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(sysDepart.getDefaultRoleId())) {
                for (Long roleId : sysDepart.getDefaultRoleId()) {
                    SysDepartRole sysDepartRole = new SysDepartRole();
                    sysDepartRole.setDepartId(sysDepart.getId());
                    sysDepartRole.setRoleId(roleId);
                    sysDepartRole.setDeleted(0);
                    sysDepartRoleMapper.insert(sysDepartRole);
                }
            }
            return true;
        } else {
            return false;
        }

    }

    @Override
    @Transactional
    public void deleteBatchWithChildren(List<Long> ids) {
        List<Long> idList = new ArrayList<>();
        for (Long id : ids) {
            idList.add(id);
            this.checkChildrenExists(id, idList);
        }
        this.removeByIds(idList);

    }

    /**
     * <p>
     * 根据关键字搜索相关的部门数据
     * </p>
     */
    @Override
    public List<SysDepartTreeModel> searhBy(String keyWord) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.like(SysDepart::getDepartName, keyWord);
        //update-begin--Author:huangzhilin  Date:20140417 for：[bugfree号]组织机构搜索回显优化--------------------
        SysDepartTreeModel model = new SysDepartTreeModel();
        List<SysDepart> departList = this.list(query);
        List<SysDepartTreeModel> newList = new ArrayList<>();
        if (departList.size() > 0) {
            for (SysDepart depart : departList) {
                model = new SysDepartTreeModel(depart);
                model.setChildren(null);
                //update-end--Author:huangzhilin  Date:20140417 for：[bugfree号]组织机构搜索功回显优化----------------------
                newList.add(model);
            }
            return newList;
        }
        return null;
    }

    /**
     * 根据部门id删除并且删除其可能存在的子级任何部门
     */
    @Override
    public boolean delete(Long id) {
        List<Long> idList = new ArrayList<>();
        idList.add(id);
        this.checkChildrenExists(id, idList);
        //清空部门树内存
        //FindsDepartsChildrenUtil.clearDepartIdModel();
        boolean ok = this.removeByIds(idList);
        return ok;
    }

    /**
     * delete 方法调用
     *
     * @param id
     * @param idList
     */
    private void checkChildrenExists(Long id, List<Long> idList) {
        LambdaQueryWrapper<SysDepart> query = new LambdaQueryWrapper<SysDepart>();
        query.eq(SysDepart::getParentId, id);
        List<SysDepart> departList = this.list(query);
        if (departList != null && departList.size() > 0) {
            for (SysDepart depart : departList) {
                idList.add(Long.valueOf(depart.getId()));
                this.checkChildrenExists(Long.valueOf(depart.getId()), idList);
            }
        }
    }

    @Override
    public List<SysDepart> queryUserDeparts(Integer userId) {
        return baseMapper.queryUserDeparts(userId);
    }

    @Override
    public List<SysDepart> queryDepartsByUsername(String username) {
        return baseMapper.queryDepartsByUsername(username);
    }

}
